/**
*  \file binarith.h
*
*  \brief Library for binary arithmetic.
* 
*  This module contains common definitions, macros and functions to manipulate binary data.
*
*  \author D'Aprea F.  <francesco.daprea@linde-mh.de>
*  \author Michael Kunkelmann <m.kunkelmann@webergmbh.de>
*
*
*/

#ifndef BINARITH_H_INCLUDED
#define BINARITH_H_INCLUDED

/*================================================[ public includes  ]================================================*/
#include "../cfg/prj.h"

/*================================================[ public defines   ]================================================*/

#define BIN_U32_NO_OF_BITS      		32U 	/**< size 32-bit value */
#define BIN_NO_OF_BITS_PER_BYTE  		8U 		/**< no of bits per byte */

#define BIN_CONV_BITS_TO_BYTES(bits)    (  bits >> 0x03U )        /**< converts number of bits to full bytes */
#define BIN_CONV_BYTES_TO_BITS(bytes)   ( bytes << 0x03U )        /**< converts number of bytes to bits */


/**
*  This macro converts the endian of a 16-bit value
*  from litte to big endian or big to little endian.
*/
#define BIN_CONV_ENDIAN_U16( x ) ( x = (( x << 8U ) & 0xFF00U ) | \
		                               (( x >> 8U ) & 0x00FFU ))


/**
*  This macro converts the endian of a 32-bit value
*  from litte to big endian or big to little endian.
*/
#define BIN_CONV_ENDIAN_U32( x ) ( x = ( ( x << 24U ) \
                                       | ( ( x << 8U ) & 0x00FF0000UL ) \
                                       | ( ( x >> 8U ) & 0x0000FF00UL ) \
                                       | ( x >> 24U ) \
                                       ) \
                                 )

/*================================================[ public datatypes ]================================================*/

/*================================================[ public variables ]================================================*/

/*================================================[ public functions ]================================================*/

/**
*  This function rotates a 32bit unsigned value left n bits.
*
*  \param value 32-bit value to rotate.
*  \param n     Number of bits to rotate. It is not safe to pass a value that is bigger than 32.
*               Bigger values have to be modulo divided by BIN_U32_NO_OF_BITS before passing.
*
*  \return Rotated value.
*/
STATIC_INLINE U32 bin_rotate_left_U32( const U32 value, const U8 n )
{
   return ( ( value << n ) | ( value >> ( BIN_U32_NO_OF_BITS - n ) ) );
      /* BIN_U32_NO_OF_BITS = sizeof(U32) * BIN_NO_OF_BITS_PER_BYTE */
}

/**
*  This function rotates a 32bit unsigned value right n bits.
*
*  \param value 32-bit value to rotate.
*  \param n     Number of bits to rotate. It is not safe to pass a value that is bigger than 32.
*               Bigger values have to be modulo divided by BIN_U32_NO_OF_BITS before passing.
*
*  \return Rotated value.
*/
STATIC_INLINE U32 bin_rotate_right_U32( const U32 value, const U8 n )
{
   return ( ( value >> n ) | ( value << ( BIN_U32_NO_OF_BITS - n ) ) );
      /* BIN_U32_NO_OF_BITS = sizeof(U32) * BIN_NO_OF_BITS_PER_BYTE */
}

                         
/**
*  This function converts the endian of a 32-bit value
*  from litte to big endian or big to little endian.
*
*  \param arg_value Value to convert.
*
*  \return Converted value.
*/                     
STATIC_INLINE U32 bin_conv_endian_U32( U32 arg_value )
{
   return BIN_CONV_ENDIAN_U32( arg_value );
}


/**
*  This function converts the endian of a 16-bit value
*  from litte to big endian or big to little endian.
*
*  \param arg_value Value to convert.
*
*  \return Converted value.
*/
STATIC_INLINE U16 bin_conv_endian_U16( U16 arg_value )
{
   return BIN_CONV_ENDIAN_U16( arg_value );
}

#endif

/***********************************************************************************************************************
*                             Copyright 2011 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/

